package com.settlement.system.manager;

import com.settlement.system.common.annotation.AdmitCustomizedExpore;
import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelProperty;
import com.settlement.system.controller.ExcelController;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;

import jakarta.annotation.Resource;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Stream;

/**
 * 自定义导出的管理
 *
 * @author Ximi
 * @since 2020/11/17
 */
@Component
public class CustomizedExporeManager implements InitializingBean {

    @Resource
    private List<ExcelController> controllerList;

    private Map<String, List<CustomizedField>> menuFieldsMap = new HashMap<>(16);

    private Map<String,String> menuAndClassNameMap = new HashMap<>(16);

    @Override
    public void afterPropertiesSet() throws Exception {

        for (ExcelController excelController : controllerList) {
            Class cs = excelController.getModelClass();
            AdmitCustomizedExpore expore = (AdmitCustomizedExpore) cs.getDeclaredAnnotation(AdmitCustomizedExpore.class);
            if (expore != null) {
                //实体一样的，就认为导出的也一样。只是确认 相同的注解不要出现在不同的类上就行了。
                //如果要重新复制一个实体类出来不太美观，就这样处理一下。
                List<CustomizedField> customizedFields = menuFieldsMap.get(expore.name());
                if (customizedFields != null) {
                    String className = menuAndClassNameMap.get(expore.name());
                    if(!cs.getName().equals(className)){
                        throw new IllegalArgumentException(cs.getName() + "的注解 AdmitCustomizedExpore.name:" + expore.name() + "重复");
                    }
                }
                doParseExpore(expore, cs);
            }
        }
    }

    private void doParseExpore(AdmitCustomizedExpore expore, Class cs) {
        menuFieldsMap.put(expore.name(), new ArrayList<>());
        menuAndClassNameMap.put(expore.name(),cs.getName());
        Field[] fields = cs.getDeclaredFields();
        Stream.of(fields).forEach(field -> {
            ExcelProperty excelProperty = field.getAnnotation(ExcelProperty.class);
            ExcelIgnore ignore = field.getAnnotation(ExcelIgnore.class);
            // boolean flag = excelProperty != null && (ignore == null || !ignore.isWriteIgnore());
            boolean flag = false;
            if (flag) {
                CustomizedField customizedField = new CustomizedField();
                customizedField.fieldDescription = excelProperty.value()[0];
                customizedField.fieldName = field.getName();
                menuFieldsMap.get(expore.name()).add(customizedField);
            }
        });
    }

    public static class CustomizedField implements Serializable {
        public String fieldDescription;
        public String fieldName;

        public String getFieldDescription() {
            return fieldDescription;
        }

        public void setFieldDescription(String fieldDescription) {
            this.fieldDescription = fieldDescription;
        }

        public String getFieldName() {
            return fieldName;
        }

        public void setFieldName(String fieldName) {
            this.fieldName = fieldName;
        }
    }

    public List<String> getAllMenu() {
        ArrayList<String> arrayList = new ArrayList<>();
        arrayList.addAll(menuFieldsMap.keySet());
        return arrayList;
    }

    public List<CustomizedField> getCustomizedField(String name) {
        return menuFieldsMap.get(name);
    }
}
